package com.wang.tool.dagre.node;

import com.wang.tool.dagre.DagreContext;

import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * 异步Future模板
 * @author shaopeng
 * @date 2022/12/18
 */
public abstract class AbsFutureDagreNode<T> extends AbsDagreNode<T> {

    @Override
    public final boolean isSync() {
        return false;
    }

    @Override
    protected final Object doExecute(DagreContext<T> context) throws Throwable {
        Future future = asyncExecute(context);
        try {
            Integer remainTime = context.calRemainTime();
            int wait = remainTime == null ? getTimeout(context) : Math.min(remainTime, getTimeout(context));
            return future.get(wait, TimeUnit.MILLISECONDS);
        } finally {
            if (!future.isDone()) {
                future.cancel(true);
            }
        }
    }

    /**
     * 异步future
     *
     * @param context 非空
     * @return
     */
    protected abstract Future asyncExecute(DagreContext<T> context) throws Throwable;

    /**
     * 超时时间 单位ms
     *
     * @param context 非空
     * @return
     */
    protected abstract int getTimeout(DagreContext<T> context);


}
